﻿/*
** Xin YUAN, 2023, BSD (2)
*/

////////////////////////////////////////////////////////////////////////////////
#ifndef __CTL_S3D_BASE_H__
#define __CTL_S3D_BASE_H__
////////////////////////////////////////////////////////////////////////////////

#ifndef __CTL_DEF_H__
	#error base.h requires def.h to be included first
#endif

////////////////////////////////////////////////////////////////////////////////
namespace CTL {
////////////////////////////////////////////////////////////////////////////////

#pragma pack(push, 1)

//QuadColor
/*! \brief A type for quad color.

A type for quad color.
\note The format of color is ARGB.
\verbatim
   ARGB
MSB    LSB
Little-endian : BGRA
Big-endian : ARGB
\endverbatim
*/
class QuadColor
{
public:
	uint32_t Get() const noexcept
	{
		return m_value;
	}
	void Set(uint32_t v) noexcept
	{
		m_value = v;
	}
	void Make(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
	{
		m_value = ((((((uint32_t)a << 8) | (uint32_t)r) << 8) | (uint32_t)g) << 8) | (uint32_t)b;
	}
	uint8_t A() const noexcept
	{
		return (uint8_t)((m_value >> 24) & 0x000000FF);
	}
	uint8_t R() const noexcept
	{
		return (uint8_t)((m_value >> 16) & 0x000000FF);
	}
	uint8_t G() const noexcept
	{
		return (uint8_t)((m_value >> 8) & 0x000000FF);
	}
	uint8_t B() const noexcept
	{
		return (uint8_t)(m_value & 0x000000FF);
	}
	void A(uint8_t v) noexcept
	{
		m_value &= (~(0x000000FF << 24));
		m_value |= ((uint32_t)v << 24);
	}
	void R(uint8_t v) noexcept
	{
		m_value &= (~(0x000000FF << 16));
		m_value |= ((uint32_t)v << 16);
	}
	void G(uint8_t v) noexcept
	{
		m_value &= (~(0x000000FF << 8));
		m_value |= ((uint32_t)v << 8);
	}
	void B(uint8_t v) noexcept
	{
		m_value &= (~0x000000FF);
		m_value |= ((uint32_t)v);
	}

private:
	uint32_t m_value;
};

#pragma pack(pop)

//BlendQuadColor
/*! \brief Blend two colors.

Blend two colors.
\param clr1 [in] The first color.
\param clr2 [in] The second color.
\param uPercent [in] The opacity degree about clr2. The range of this value is [0, 100].
\return The result color.
*/
inline QuadColor BlendQuadColor(QuadColor clr1, QuadColor clr2, uint32_t uPercent) noexcept
{
	assert( uPercent >= 0 && uPercent <= 100 );
	QuadColor ret;
	ret.Make(
		((uint32_t)clr1.R() * (100 - uPercent) + (uint32_t)clr2.R() * uPercent) / 100,
		((uint32_t)clr1.G() * (100 - uPercent) + (uint32_t)clr2.G() * uPercent) / 100,
		((uint32_t)clr1.B() * (100 - uPercent) + (uint32_t)clr2.B() * uPercent) / 100,
		((uint32_t)clr1.A() * (100 - uPercent) + (uint32_t)clr2.A() * uPercent) / 100
		);
	return ret;
}

////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
#endif
////////////////////////////////////////////////////////////////////////////////
